//**** Frame FAS search and check module ***//

module FRM_SCRM(
   RESET,
   TCLK_155M,

   DBIN_TDATA,
   DBIN_FCNT8,
   DBIN_FCNT270,
   DBIN_FCNT9,
   MPI_SRCM_EN,

   DBOUT_TDATA
   );

input               RESET;
input               TCLK_155M;

input[63:0]         DBIN_TDATA;
input[2:0]          DBIN_FCNT8;
input[8:0]          DBIN_FCNT270;
input[3:0]          DBIN_FCNT9;
input               MPI_SRCM_EN;

output reg[63:0]    DBOUT_TDATA;
reg                 SCRM_ADDR_CNT_EN;
reg[6:0]            SCRM_ADDR_CNT;
wire[63:0]          SCRM_TBL_RDATA;
reg[63:0]           SCRM_VRCTOR;
reg[63:0]           SCRM_TDATA;
reg[2:0]            SCRM_FCNT8;
reg[8:0]            SCRM_FCNT270;
reg[3:0]            SCRM_FCNT9;
reg                 SCRM_SCRAMBLE_EN;

reg[2:0]            B1CAL_FCNT8;
reg[8:0]            B1CAL_FCNT270;
reg[3:0]            B1CAL_FCNT9;
reg[7:0]            B1CAL_FIANL_VALUE;
reg[7:0]            B1CAL_CALC_VALUE;
reg                 B1CAL_CALCEN;

always @( DBIN_FCNT9 or DBIN_FCNT270 or DBIN_FCNT8) begin
   if ( DBIN_FCNT9[3:0]==4'd0 && DBIN_FCNT270[8:0]<9'd8 )
         SCRM_ADDR_CNT_EN           <= 1'b0;
   else if ( DBIN_FCNT9[3:0]==4'd0 && DBIN_FCNT270[8:0]==9'd8 ) begin
      if ( DBIN_FCNT8[2:0]==3'd6 || DBIN_FCNT8[2:0]==3'd7 )
         SCRM_ADDR_CNT_EN           <= 1'b1;
      else
         SCRM_ADDR_CNT_EN           <= 1'b0;
   end
   else if ( DBIN_FCNT9[3:0]==4'd8 && DBIN_FCNT270[8:0]==9'd269 ) begin
      if ( DBIN_FCNT8[2:0]==3'd6 || DBIN_FCNT8[2:0]==3'd7 )
         SCRM_ADDR_CNT_EN           <= 1'b0;
      else
         SCRM_ADDR_CNT_EN           <= 1'b1;
   end
   else begin
         SCRM_ADDR_CNT_EN           <= 1'b1;
   end
end

always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      SCRM_ADDR_CNT[6:0]            <=7'd0;
   else begin
      if ( SCRM_ADDR_CNT_EN==1'b0 )
          SCRM_ADDR_CNT[6:0]        <=7'd0;
      else if ( SCRM_ADDR_CNT[6:0]==7'd126 )
          SCRM_ADDR_CNT[6:0]        <=7'd0;
      else
          SCRM_ADDR_CNT[6:0]        <=SCRM_ADDR_CNT[6:0] +7'd1;
   end
end

XLNX_SCRM_ROM   INST_SCRM_TABLE(   // 2 clock cycles delay in reading
   .clka        ( TCLK_155M ),
   .addra       ( SCRM_ADDR_CNT[6:0] ),
   .douta       ( SCRM_TBL_RDATA[63:0] )
   );

always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      SCRM_TDATA[63:0]                   <= 64'd0;
   else begin
      if ( DBIN_FCNT9[3:0]==4'd1 && DBIN_FCNT270[8:0]==9'd0 &&  DBIN_FCNT8[2:0]==3'd0 )
         SCRM_TDATA[63:0]                <= {B1CAL_FIANL_VALUE[7:0], 56'd0};
      else
         SCRM_TDATA[63:0]                <= DBIN_TDATA[63:0];
   end
end
always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 ) begin
      SCRM_FCNT8[2:0]                <= 3'd0;
      SCRM_FCNT270[8:0]              <= 9'd0;
      SCRM_FCNT9[3:0]                <= 4'd0;
      SCRM_VRCTOR[63:0]              <= 64'd0;
   end
   else begin
      SCRM_FCNT8[2:0]                <= DBIN_FCNT8[2:0];
      SCRM_FCNT270[8:0]              <= DBIN_FCNT270[8:0];
      SCRM_FCNT9[3:0]                <= DBIN_FCNT9[3:0];
      SCRM_VRCTOR[63:0]              <= SCRM_TBL_RDATA[63:0];
   end
end

//
always @(MPI_SRCM_EN or SCRM_FCNT9 or SCRM_FCNT270) begin
      if ( MPI_SRCM_EN==1'b0 )
         SCRM_SCRAMBLE_EN             <= 1'b0;
      else begin
         if ( SCRM_FCNT9[3:0]==4'd0 && SCRM_FCNT270[8:0]<9'd9 )
            SCRM_SCRAMBLE_EN          <= 1'b0;
         else
            SCRM_SCRAMBLE_EN          <= 1'b1;
      end
end
always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      DBOUT_TDATA[63:0]               <= 64'd0;
   else begin
      if ( SCRM_SCRAMBLE_EN==1'b1 )
         DBOUT_TDATA[63:0]            <= SCRM_TDATA[63:0] ^ SCRM_VRCTOR[63:0];
      else
         DBOUT_TDATA[63:0]            <= SCRM_TDATA[63:0];
   end
end



always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )  begin
      B1CAL_FCNT8[2:0]                <= 3'd0;
      B1CAL_FCNT270[8:0]              <= 9'd0;
      B1CAL_FCNT9[3:0]                <= 4'd0;
   end
   else begin
      B1CAL_FCNT8[2:0]                <= SCRM_FCNT8[2:0];
      B1CAL_FCNT270[8:0]              <= SCRM_FCNT270[8:0];
      B1CAL_FCNT9[3:0]                <= SCRM_FCNT9[3:0];
   end
end
always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      B1CAL_CALC_VALUE[7:0]         <= 8'd0;
   else begin
      if ( B1CAL_FCNT9[3:0]==4'd0 && B1CAL_FCNT270[8:0]==9'd0 &&  B1CAL_FCNT8[2:0]==3'd0 ) begin
         B1CAL_CALC_VALUE[7]        <= DBOUT_TDATA[7] ^ DBOUT_TDATA[15] ^ DBOUT_TDATA[23] ^ DBOUT_TDATA[31] ^ DBOUT_TDATA[39] ^ DBOUT_TDATA[47] ^ DBOUT_TDATA[55] ^ DBOUT_TDATA[63];
         B1CAL_CALC_VALUE[6]        <= DBOUT_TDATA[6] ^ DBOUT_TDATA[14] ^ DBOUT_TDATA[22] ^ DBOUT_TDATA[30] ^ DBOUT_TDATA[38] ^ DBOUT_TDATA[46] ^ DBOUT_TDATA[54] ^ DBOUT_TDATA[62];
         B1CAL_CALC_VALUE[5]        <= DBOUT_TDATA[5] ^ DBOUT_TDATA[13] ^ DBOUT_TDATA[21] ^ DBOUT_TDATA[29] ^ DBOUT_TDATA[37] ^ DBOUT_TDATA[45] ^ DBOUT_TDATA[53] ^ DBOUT_TDATA[61];
         B1CAL_CALC_VALUE[4]        <= DBOUT_TDATA[4] ^ DBOUT_TDATA[12] ^ DBOUT_TDATA[20] ^ DBOUT_TDATA[28] ^ DBOUT_TDATA[36] ^ DBOUT_TDATA[44] ^ DBOUT_TDATA[52] ^ DBOUT_TDATA[60];
         B1CAL_CALC_VALUE[3]        <= DBOUT_TDATA[3] ^ DBOUT_TDATA[11] ^ DBOUT_TDATA[19] ^ DBOUT_TDATA[27] ^ DBOUT_TDATA[35] ^ DBOUT_TDATA[43] ^ DBOUT_TDATA[51] ^ DBOUT_TDATA[59];
         B1CAL_CALC_VALUE[2]        <= DBOUT_TDATA[2] ^ DBOUT_TDATA[10] ^ DBOUT_TDATA[18] ^ DBOUT_TDATA[26] ^ DBOUT_TDATA[34] ^ DBOUT_TDATA[42] ^ DBOUT_TDATA[50] ^ DBOUT_TDATA[58];
         B1CAL_CALC_VALUE[1]        <= DBOUT_TDATA[1] ^ DBOUT_TDATA[9]  ^ DBOUT_TDATA[17] ^ DBOUT_TDATA[25] ^ DBOUT_TDATA[33] ^ DBOUT_TDATA[41] ^ DBOUT_TDATA[49] ^ DBOUT_TDATA[57];
         B1CAL_CALC_VALUE[0]        <= DBOUT_TDATA[0] ^ DBOUT_TDATA[8]  ^ DBOUT_TDATA[16] ^ DBOUT_TDATA[24] ^ DBOUT_TDATA[32] ^ DBOUT_TDATA[40] ^ DBOUT_TDATA[48] ^ DBOUT_TDATA[56];
      end
      else begin
         B1CAL_CALC_VALUE[7]        <= B1CAL_CALC_VALUE[7] ^ DBOUT_TDATA[7] ^ DBOUT_TDATA[15] ^ DBOUT_TDATA[23] ^ DBOUT_TDATA[31] ^ DBOUT_TDATA[39] ^ DBOUT_TDATA[47] ^ DBOUT_TDATA[55] ^ DBOUT_TDATA[63];
         B1CAL_CALC_VALUE[6]        <= B1CAL_CALC_VALUE[6] ^ DBOUT_TDATA[6] ^ DBOUT_TDATA[14] ^ DBOUT_TDATA[22] ^ DBOUT_TDATA[30] ^ DBOUT_TDATA[38] ^ DBOUT_TDATA[46] ^ DBOUT_TDATA[54] ^ DBOUT_TDATA[62];
         B1CAL_CALC_VALUE[5]        <= B1CAL_CALC_VALUE[5] ^ DBOUT_TDATA[5] ^ DBOUT_TDATA[13] ^ DBOUT_TDATA[21] ^ DBOUT_TDATA[29] ^ DBOUT_TDATA[37] ^ DBOUT_TDATA[45] ^ DBOUT_TDATA[53] ^ DBOUT_TDATA[61];
         B1CAL_CALC_VALUE[4]        <= B1CAL_CALC_VALUE[4] ^ DBOUT_TDATA[4] ^ DBOUT_TDATA[12] ^ DBOUT_TDATA[20] ^ DBOUT_TDATA[28] ^ DBOUT_TDATA[36] ^ DBOUT_TDATA[44] ^ DBOUT_TDATA[52] ^ DBOUT_TDATA[60];
         B1CAL_CALC_VALUE[3]        <= B1CAL_CALC_VALUE[3] ^ DBOUT_TDATA[3] ^ DBOUT_TDATA[11] ^ DBOUT_TDATA[19] ^ DBOUT_TDATA[27] ^ DBOUT_TDATA[35] ^ DBOUT_TDATA[43] ^ DBOUT_TDATA[51] ^ DBOUT_TDATA[59];
         B1CAL_CALC_VALUE[2]        <= B1CAL_CALC_VALUE[2] ^ DBOUT_TDATA[2] ^ DBOUT_TDATA[10] ^ DBOUT_TDATA[18] ^ DBOUT_TDATA[26] ^ DBOUT_TDATA[34] ^ DBOUT_TDATA[42] ^ DBOUT_TDATA[50] ^ DBOUT_TDATA[58];
         B1CAL_CALC_VALUE[1]        <= B1CAL_CALC_VALUE[1] ^ DBOUT_TDATA[1] ^ DBOUT_TDATA[9]  ^ DBOUT_TDATA[17] ^ DBOUT_TDATA[25] ^ DBOUT_TDATA[33] ^ DBOUT_TDATA[41] ^ DBOUT_TDATA[49] ^ DBOUT_TDATA[57];
         B1CAL_CALC_VALUE[0]        <= B1CAL_CALC_VALUE[0] ^ DBOUT_TDATA[0] ^ DBOUT_TDATA[8]  ^ DBOUT_TDATA[16] ^ DBOUT_TDATA[24] ^ DBOUT_TDATA[32] ^ DBOUT_TDATA[40] ^ DBOUT_TDATA[48] ^ DBOUT_TDATA[56];
      end
   end
end
always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      B1CAL_FIANL_VALUE[7:0]        <= 8'd1;
   else begin
      if ( B1CAL_FCNT9[3:0]==4'd8 && B1CAL_FCNT270[8:0]==9'd269 &&  B1CAL_FCNT8[2:0]==3'd7) begin
         B1CAL_FIANL_VALUE[7]       <= B1CAL_CALC_VALUE[7] ^ DBOUT_TDATA[7] ^ DBOUT_TDATA[15] ^ DBOUT_TDATA[23] ^ DBOUT_TDATA[31] ^ DBOUT_TDATA[39] ^ DBOUT_TDATA[47] ^ DBOUT_TDATA[55] ^ DBOUT_TDATA[63];
         B1CAL_FIANL_VALUE[6]       <= B1CAL_CALC_VALUE[6] ^ DBOUT_TDATA[6] ^ DBOUT_TDATA[14] ^ DBOUT_TDATA[22] ^ DBOUT_TDATA[30] ^ DBOUT_TDATA[38] ^ DBOUT_TDATA[46] ^ DBOUT_TDATA[54] ^ DBOUT_TDATA[62];
         B1CAL_FIANL_VALUE[5]       <= B1CAL_CALC_VALUE[5] ^ DBOUT_TDATA[5] ^ DBOUT_TDATA[13] ^ DBOUT_TDATA[21] ^ DBOUT_TDATA[29] ^ DBOUT_TDATA[37] ^ DBOUT_TDATA[45] ^ DBOUT_TDATA[53] ^ DBOUT_TDATA[61];
         B1CAL_FIANL_VALUE[4]       <= B1CAL_CALC_VALUE[4] ^ DBOUT_TDATA[4] ^ DBOUT_TDATA[12] ^ DBOUT_TDATA[20] ^ DBOUT_TDATA[28] ^ DBOUT_TDATA[36] ^ DBOUT_TDATA[44] ^ DBOUT_TDATA[52] ^ DBOUT_TDATA[60];
         B1CAL_FIANL_VALUE[3]       <= B1CAL_CALC_VALUE[3] ^ DBOUT_TDATA[3] ^ DBOUT_TDATA[11] ^ DBOUT_TDATA[19] ^ DBOUT_TDATA[27] ^ DBOUT_TDATA[35] ^ DBOUT_TDATA[43] ^ DBOUT_TDATA[51] ^ DBOUT_TDATA[59];
         B1CAL_FIANL_VALUE[2]       <= B1CAL_CALC_VALUE[2] ^ DBOUT_TDATA[2] ^ DBOUT_TDATA[10] ^ DBOUT_TDATA[18] ^ DBOUT_TDATA[26] ^ DBOUT_TDATA[34] ^ DBOUT_TDATA[42] ^ DBOUT_TDATA[50] ^ DBOUT_TDATA[58];
         B1CAL_FIANL_VALUE[1]       <= B1CAL_CALC_VALUE[1] ^ DBOUT_TDATA[1] ^ DBOUT_TDATA[9]  ^ DBOUT_TDATA[17] ^ DBOUT_TDATA[25] ^ DBOUT_TDATA[33] ^ DBOUT_TDATA[41] ^ DBOUT_TDATA[49] ^ DBOUT_TDATA[57];
         B1CAL_FIANL_VALUE[0]       <= B1CAL_CALC_VALUE[0] ^ DBOUT_TDATA[0] ^ DBOUT_TDATA[8]  ^ DBOUT_TDATA[16] ^ DBOUT_TDATA[24] ^ DBOUT_TDATA[32] ^ DBOUT_TDATA[40] ^ DBOUT_TDATA[48] ^ DBOUT_TDATA[56];
      end
   end
end

endmodule
